Skip to content

Add skeleton structure for tiering status API#21017

Merged
gbbafna merged 1 commit into
opensearch-project:mainfrom
GeekGlider:feature/tiered-storage-skeleton
Apr 6, 2026
Merged

Add skeleton structure for tiering status API#21017
gbbafna merged 1 commit into
opensearch-project:mainfrom
GeekGlider:feature/tiered-storage-skeleton

Conversation

@GeekGlider
Copy link
Copy Markdown
Contributor

@GeekGlider GeekGlider commented Mar 27, 2026

Description

Adds the skeleton structure for the tiering status API in server core (org.opensearch.storage.action.tiering.status).

What's locked down in this PR:

  • Action typesGetTieringStatusAction (indices:admin/_tier/get), ListTieringStatusAction (cluster:admin/_tier/all)
  • Request/response modelsGetTieringStatusRequest, GetTieringStatusResponse, ListTieringStatusRequest, ListTieringStatusResponse, TieringStatus with serialized field declarations
  • REST handlersRestGetTieringStatusAction (GET /{index}/_tier), RestListTieringStatusAction (GET /_tier/all)
  • Transport actionsTransportGetTieringStatusAction, TransportListTieringStatusAction

What's NOT in this PR:

  • No implementation logic — all method bodies throw UnsupportedOperationException("Not yet implemented")
  • No tests — nothing to test since there's no implementation
  • TieringService dependencies will be wired in the implementation PR

Related Issues

Part of the tiered storage skeleton for WritableWarm — resolves #21078

Check List

  • Functionality includes testing.
  • API changes companion pull request created, if applicable.
  • Public documentation issue/PR created, if applicable.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

@GeekGlider GeekGlider requested a review from a team as a code owner March 27, 2026 12:56
@github-actions
Copy link
Copy Markdown
Contributor

Failed to generate code suggestions for PR

@github-actions
Copy link
Copy Markdown
Contributor

❌ Gradle check result for f378ff6: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@GeekGlider GeekGlider force-pushed the feature/tiered-storage-skeleton branch from f378ff6 to 52a6cf3 Compare March 29, 2026 07:02
@github-actions
Copy link
Copy Markdown
Contributor

Failed to generate code suggestions for PR

@github-actions
Copy link
Copy Markdown
Contributor

❌ Gradle check result for 52a6cf3: null

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@GeekGlider GeekGlider force-pushed the feature/tiered-storage-skeleton branch from 52a6cf3 to c2f0570 Compare March 29, 2026 09:22
@github-actions
Copy link
Copy Markdown
Contributor

Failed to generate code suggestions for PR

@github-actions
Copy link
Copy Markdown
Contributor

❌ Gradle check result for c2f0570: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 29, 2026

PR Reviewer Guide 🔍

(Review updated until commit 6272274)

Here are some key observations to aid the review process:

🧪 No relevant tests
🔒 No security concerns identified
✅ No TODO sections
🔀 No multiple PR themes
⚡ Recommended focus areas for review

Inconsistent Constructor

GetTieringStatusAction has a public constructor while ListTieringStatusAction has a private constructor. Since both are singletons, the constructor for GetTieringStatusAction should also be private to prevent external instantiation and enforce the singleton pattern.

public GetTieringStatusAction() {
    super(NAME, GetTieringStatusResponse::new);
}
Null validate()

GetTieringStatusRequest.validate() throws UnsupportedOperationException, while ListTieringStatusRequest.validate() returns null. These two are inconsistent. When the transport layer is wired up, calling validate() on GetTieringStatusRequest will throw rather than returning a validation result, which could cause unexpected failures. Consider aligning both to return null (no validation) or a consistent stub.

public ActionRequestValidationException validate() {
    throw new UnsupportedOperationException("Not yet implemented");
}
Mutable Status Field

The status field in TieringStatus is typed as String rather than an enum. Using a plain string for status values (e.g., "RUNNING", "COMPLETED") risks inconsistency and typos. Consider defining a dedicated enum type for tiering status states to enforce valid values at compile time.

private String status;
Design Mismatch

RestListTieringStatusAction extends AbstractCatAction, which is typically used for _cat API endpoints with tabular output. However, the route is /_tier/all, not a /_cat/ path. This may be an unintentional design choice — if the intent is a standard REST API, it should extend BaseRestHandler instead, similar to RestGetTieringStatusAction.

public class RestListTieringStatusAction extends AbstractCatAction {
Boolean vs boolean

The isDetailedFlagEnabled field uses the boxed Boolean type instead of primitive boolean. This allows null as a value, which could cause NullPointerException when unboxed. Unless null is a meaningful state distinct from false, prefer primitive boolean with a default of false.

private Boolean isDetailedFlagEnabled;

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 29, 2026

PR Code Suggestions ✨

Latest suggestions up to 6272274

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Enforce singleton pattern with private constructor

The constructor of GetTieringStatusAction is public, but since it uses a singleton
pattern (via INSTANCE), the constructor should be private to prevent external
instantiation and enforce the singleton contract. ListTieringStatusAction correctly
uses a private constructor, but GetTieringStatusAction does not.

server/src/main/java/org/opensearch/storage/action/tiering/status/GetTieringStatusAction.java [23-25]

-public GetTieringStatusAction() {
+private GetTieringStatusAction() {
     super(NAME, GetTieringStatusResponse::new);
 }
Suggestion importance[1-10]: 7

__

Why: The GetTieringStatusAction uses a singleton pattern via INSTANCE but has a public constructor, inconsistent with ListTieringStatusAction which correctly uses a private constructor. Making it private enforces the singleton contract and prevents unintended external instantiation.

Medium
Possible issue
Avoid partial deserialization before throwing exception

The StreamInput constructor calls super(in) before throwing
UnsupportedOperationException. This means the parent class deserialization runs
partially, which could cause resource leaks or inconsistent state. The super(in)
call should be removed or the entire constructor body should just throw, consistent
with the other skeleton constructors in this PR.

server/src/main/java/org/opensearch/storage/action/tiering/status/model/GetTieringStatusRequest.java [66-69]

 public GetTieringStatusRequest(StreamInput in) throws IOException {
-    super(in);
     throw new UnsupportedOperationException("Not yet implemented");
 }
Suggestion importance[1-10]: 4

__

Why: While calling super(in) before throwing could theoretically cause partial state initialization, since this is a skeleton/stub implementation with UnsupportedOperationException, the practical risk is minimal. However, removing super(in) would make it consistent with other stub constructors in this PR like ListTieringStatusRequest(StreamInput in).

Low

Previous suggestions

Suggestions up to commit 3e7a513
CategorySuggestion                                                                                                                                    Impact
General
Enforce singleton pattern with private constructor

The constructor of GetTieringStatusAction is public, but since it follows the
singleton pattern (like ListTieringStatusAction), it should be private to prevent
external instantiation and enforce use of the INSTANCE field.

server/src/main/java/org/opensearch/storage/action/tiering/status/GetTieringStatusAction.java [23-25]

-public GetTieringStatusAction() {
+private GetTieringStatusAction() {
     super(NAME, GetTieringStatusResponse::new);
 }
Suggestion importance[1-10]: 6

__

Why: The GetTieringStatusAction uses a singleton pattern with a public INSTANCE field, but unlike ListTieringStatusAction which has a private constructor, this class has a public constructor allowing external instantiation. Making it private enforces the singleton pattern consistently.

Low
Possible issue
Avoid partial deserialization before throwing exception

The StreamInput constructor calls super(in) before throwing, which means the parent
class deserialization runs partially before the exception is thrown. This could
leave the stream in an inconsistent state. The super(in) call should be removed or
the entire constructor body should just throw without calling super.

server/src/main/java/org/opensearch/storage/action/tiering/status/model/GetTieringStatusRequest.java [66-69]

 public GetTieringStatusRequest(StreamInput in) throws IOException {
-    super(in);
     throw new UnsupportedOperationException("Not yet implemented");
 }
Suggestion importance[1-10]: 4

__

Why: Calling super(in) before throwing UnsupportedOperationException could partially consume the stream, but since this is a stub implementation that will be replaced, the practical impact is minimal. The suggestion is technically valid but low priority given the temporary nature of the code.

Low
Suggestions up to commit 00e93b5
CategorySuggestion                                                                                                                                    Impact
General
Enforce singleton pattern with private constructor

The constructor of GetTieringStatusAction is public, but since it follows the
singleton pattern (like ListTieringStatusAction), the constructor should be private
to prevent external instantiation and enforce the singleton contract.

server/src/main/java/org/opensearch/storage/action/tiering/status/GetTieringStatusAction.java [23-25]

-public GetTieringStatusAction() {
+private GetTieringStatusAction() {
     super(NAME, GetTieringStatusResponse::new);
 }
Suggestion importance[1-10]: 6

__

Why: The GetTieringStatusAction uses a singleton pattern with a public INSTANCE field, but unlike ListTieringStatusAction which has a private constructor, this class has a public constructor allowing external instantiation. Making it private would enforce the singleton contract consistently.

Low
Possible issue
Avoid partial deserialization before throwing exception

The StreamInput constructor calls super(in) before throwing an exception. This means
the parent class deserialization runs partially, which could cause resource leaks or
inconsistent state. The super(in) call should be removed or the entire constructor
body should just throw the exception.

server/src/main/java/org/opensearch/storage/action/tiering/status/model/GetTieringStatusRequest.java [66-69]

 public GetTieringStatusRequest(StreamInput in) throws IOException {
-    super(in);
     throw new UnsupportedOperationException("Not yet implemented");
 }
Suggestion importance[1-10]: 4

__

Why: While calling super(in) before throwing is technically a concern, since this is a stub with UnsupportedOperationException and the entire class is marked as not yet implemented, the practical impact is minimal. However, removing super(in) would require a throws IOException suppression or restructuring since the constructor signature still declares IOException.

Low
Suggestions up to commit 6ef0bb2
CategorySuggestion                                                                                                                                    Impact
General
Enforce singleton pattern with private constructor

The constructor of GetTieringStatusAction is public, but since it follows the
singleton pattern (like ListTieringStatusAction), it should be private to prevent
external instantiation and enforce use of the INSTANCE field.

server/src/main/java/org/opensearch/storage/action/tiering/status/GetTieringStatusAction.java [23-25]

-public GetTieringStatusAction() {
+private GetTieringStatusAction() {
     super(NAME, GetTieringStatusResponse::new);
 }
Suggestion importance[1-10]: 7

__

Why: The GetTieringStatusAction uses a singleton pattern with a public INSTANCE field, but unlike ListTieringStatusAction which has a private constructor, this class has a public constructor allowing external instantiation. Making it private enforces the singleton pattern consistently.

Medium
Possible issue
Avoid partial deserialization before throwing

The stream constructor calls super(in) before throwing, which may partially
deserialize state and leave the object in an inconsistent state. Since this is a
skeleton, it's safer to throw before calling super(in), or at minimum be consistent
with other stream constructors in this PR that throw without calling super.

server/src/main/java/org/opensearch/storage/action/tiering/status/model/GetTieringStatusRequest.java [66-69]

 public GetTieringStatusRequest(StreamInput in) throws IOException {
-    super(in);
     throw new UnsupportedOperationException("Not yet implemented");
 }
Suggestion importance[1-10]: 3

__

Why: While technically valid, this is a skeleton PR where all stream constructors throw UnsupportedOperationException. The super(in) call before throwing is a minor inconsistency, but since this is placeholder code to be implemented later, the practical impact is minimal.

Low
Suggestions up to commit a346d4d
CategorySuggestion                                                                                                                                    Impact
General
Enforce singleton pattern with private constructor

The constructor of GetTieringStatusAction is public, but the class uses a singleton
pattern via INSTANCE. Making the constructor private enforces the singleton pattern
and prevents external instantiation, which is consistent with how
ListTieringStatusAction is implemented.

server/src/main/java/org/opensearch/storage/action/tiering/status/GetTieringStatusAction.java [23-25]

-public GetTieringStatusAction() {
+private GetTieringStatusAction() {
     super(NAME, GetTieringStatusResponse::new);
 }
Suggestion importance[1-10]: 6

__

Why: The GetTieringStatusAction uses a singleton pattern via INSTANCE but has a public constructor, inconsistent with ListTieringStatusAction which correctly uses a private constructor. Making it private enforces the singleton pattern and prevents unintended external instantiation.

Low
Document uppercase normalization of target tier value

The targetTier is stored in uppercase, but getTargetTier() returns it without any
documentation about this normalization. More critically, the no-arg constructor sets
targetTier = null explicitly, while the single-arg constructor normalizes to
uppercase — callers comparing the value returned by getTargetTier() against
lowercase tier names (e.g., "_warm") will get unexpected results. Consider
normalizing consistently or documenting the uppercase contract clearly.

server/src/main/java/org/opensearch/storage/action/tiering/status/model/ListTieringStatusRequest.java [45-51]

+/**
+ * Constructs a request for the given target tier.
+ * The targetTier value is normalized to uppercase.
+ * @param targetTier the target tier (e.g., "_WARM", "_HOT"), or null for all tiers
+ */
 public ListTieringStatusRequest(String targetTier) {
     if (targetTier != null) {
         this.targetTier = targetTier.toUpperCase(Locale.ROOT);
     } else {
         this.targetTier = null;
     }
 }
Suggestion importance[1-10]: 2

__

Why: The suggestion only adds documentation/comments to the existing code without changing any logic. The improved_code is functionally identical to the existing_code, just with an added Javadoc comment, which falls into the documentation category.

Low
Possible issue
Avoid partial initialization before throwing exception

The StreamInput constructor calls super(in) before throwing
UnsupportedOperationException. This means the parent class partially initializes
state before the exception is thrown, which could cause resource leaks or
inconsistent state. The super(in) call should be removed or the entire constructor
body should just throw the exception without calling super.

server/src/main/java/org/opensearch/storage/action/tiering/status/model/GetTieringStatusRequest.java [66-69]

 public GetTieringStatusRequest(StreamInput in) throws IOException {
-    super(in);
     throw new UnsupportedOperationException("Not yet implemented");
 }
Suggestion importance[1-10]: 4

__

Why: Calling super(in) before throwing UnsupportedOperationException causes partial parent class initialization, which could lead to resource leaks. However, since this is a stub/skeleton PR with all methods throwing UnsupportedOperationException, the practical impact is limited until the implementation is added.

Low
Suggestions up to commit a92526e
CategorySuggestion                                                                                                                                    Impact
General
Enforce singleton pattern with private constructor

The constructor of GetTieringStatusAction is public, but since it uses a singleton
pattern (via INSTANCE), the constructor should be private to prevent external
instantiation and enforce the singleton contract, consistent with how
ListTieringStatusAction is implemented.

server/src/main/java/org/opensearch/storage/action/tiering/status/GetTieringStatusAction.java [23-25]

-public GetTieringStatusAction() {
+private GetTieringStatusAction() {
     super(NAME, GetTieringStatusResponse::new);
 }
Suggestion importance[1-10]: 6

__

Why: The GetTieringStatusAction uses a singleton pattern via INSTANCE but has a public constructor, inconsistent with ListTieringStatusAction which correctly uses a private constructor. Making it private enforces the singleton contract and prevents unintended external instantiation.

Low
Possible issue
Remove partial superclass deserialization before stub exception

The StreamInput constructor calls super(in) before throwing the exception. This
means the parent class deserialization runs partially, which could cause
inconsistent state or misleading errors. The super(in) call should be removed or the
entire constructor body should just throw, consistent with other skeleton
constructors in this PR (e.g., ListTieringStatusRequest).

server/src/main/java/org/opensearch/storage/action/tiering/status/model/GetTieringStatusRequest.java [66-69]

 public GetTieringStatusRequest(StreamInput in) throws IOException {
-    super(in);
     throw new UnsupportedOperationException("Not yet implemented");
 }
Suggestion importance[1-10]: 5

__

Why: Calling super(in) before throwing UnsupportedOperationException causes partial parent class deserialization, which is inconsistent with other skeleton constructors in this PR (e.g., ListTieringStatusRequest) that skip the super(in) call entirely. However, since this is a stub/skeleton PR, the practical impact is limited until implementation.

Low

@GeekGlider GeekGlider force-pushed the feature/tiered-storage-skeleton branch from 96b9419 to 130e125 Compare March 29, 2026 16:06
@github-actions
Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit 130e125

@github-actions
Copy link
Copy Markdown
Contributor

✅ Gradle check result for 130e125: SUCCESS

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 29, 2026

Codecov Report

❌ Patch coverage is 0% with 126 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.28%. Comparing base (d26ad17) to head (6272274).
⚠️ Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
...age/action/tiering/status/model/TieringStatus.java 0.00% 48 Missing ⚠️
.../tiering/status/model/GetTieringStatusRequest.java 0.00% 19 Missing ⚠️
...tiering/status/model/ListTieringStatusRequest.java 0.00% 13 Missing ⚠️
...tiering/status/model/GetTieringStatusResponse.java 0.00% 8 Missing ⚠️
...iering/status/model/ListTieringStatusResponse.java 0.00% 7 Missing ⚠️
...ering/status/rest/RestListTieringStatusAction.java 0.00% 7 Missing ⚠️
...tus/transport/TransportGetTieringStatusAction.java 0.00% 7 Missing ⚠️
...us/transport/TransportListTieringStatusAction.java 0.00% 7 Missing ⚠️
...iering/status/rest/RestGetTieringStatusAction.java 0.00% 4 Missing ⚠️
.../action/tiering/status/GetTieringStatusAction.java 0.00% 3 Missing ⚠️
... and 1 more
Additional details and impacted files
@@             Coverage Diff              @@
##               main   #21017      +/-   ##
============================================
- Coverage     73.35%   73.28%   -0.08%     
+ Complexity    73209    73167      -42     
============================================
  Files          5921     5932      +11     
  Lines        333798   333924     +126     
  Branches      48124    48125       +1     
============================================
- Hits         244862   244719     -143     
- Misses        69387    69643     +256     
- Partials      19549    19562      +13     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

@chaitanya588 chaitanya588 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In few classes, i am seeing default constructors. Can you add the specific overloaded constructors here?

  1. TransportTierAction
  2. TransportGetTieringStatusAction
  3. TransportListTieringStatusAction
  4. TransportCancelTierAction

Comment thread server/src/main/java/org/opensearch/storage/common/tiering/TieringUtils.java Outdated
@GeekGlider GeekGlider force-pushed the feature/tiered-storage-skeleton branch from 130e125 to e96ceb8 Compare March 30, 2026 05:23
@github-actions
Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit e96ceb8

@github-actions
Copy link
Copy Markdown
Contributor

❌ Gradle check result for e96ceb8: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@GeekGlider GeekGlider force-pushed the feature/tiered-storage-skeleton branch from e96ceb8 to a30ef73 Compare March 30, 2026 06:33
@github-actions
Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit a30ef73

@github-actions
Copy link
Copy Markdown
Contributor

✅ Gradle check result for a30ef73: SUCCESS

@GeekGlider GeekGlider force-pushed the feature/tiered-storage-skeleton branch from a30ef73 to a81330c Compare March 30, 2026 12:19
@github-actions
Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit a81330c

@github-actions
Copy link
Copy Markdown
Contributor

❌ Gradle check result for a81330c: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@GeekGlider GeekGlider force-pushed the feature/tiered-storage-skeleton branch from a81330c to ed51490 Compare March 30, 2026 17:02
@github-actions
Copy link
Copy Markdown
Contributor

Failed to generate code suggestions for PR

@GeekGlider GeekGlider force-pushed the feature/tiered-storage-skeleton branch from a346d4d to 6ef0bb2 Compare April 4, 2026 08:21
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 4, 2026

Persistent review updated to latest commit 6ef0bb2

@GeekGlider GeekGlider force-pushed the feature/tiered-storage-skeleton branch from 6ef0bb2 to 00e93b5 Compare April 4, 2026 08:44
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 4, 2026

Persistent review updated to latest commit 00e93b5

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 4, 2026

✅ Gradle check result for 00e93b5: SUCCESS

@GeekGlider GeekGlider force-pushed the feature/tiered-storage-skeleton branch from 00e93b5 to 3e7a513 Compare April 5, 2026 06:37
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 5, 2026

Persistent review updated to latest commit 3e7a513

Signed-off-by: Kavya Aggarwal <kavyaagg@amazon.com>
@GeekGlider GeekGlider force-pushed the feature/tiered-storage-skeleton branch from 3e7a513 to 6272274 Compare April 5, 2026 07:29
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 5, 2026

Persistent review updated to latest commit 6272274

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 5, 2026

✅ Gradle check result for 6272274: SUCCESS

@gbbafna gbbafna merged commit 63f64c7 into opensearch-project:main Apr 6, 2026
14 of 15 checks passed
@github-project-automation github-project-automation Bot moved this from 👀 In review to ✅ Done in Storage Project Board Apr 6, 2026
@andrross
Copy link
Copy Markdown
Member

andrross commented Apr 7, 2026

FYI @gbbafna @GeekGlider We're no longer tracking changes in CHANGELOG, see #21071

aparajita31pandey pushed a commit to aparajita31pandey/OpenSearch that referenced this pull request Apr 18, 2026
Signed-off-by: Kavya Aggarwal <kavyaagg@amazon.com>
Signed-off-by: Aparajita Pandey <aparajita31pandey@gmail.com>
pradeep-L pushed a commit to pradeep-L/OpenSearch that referenced this pull request Apr 21, 2026
Signed-off-by: Kavya Aggarwal <kavyaagg@amazon.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Enhancement or improvement to existing feature or request Storage Issues and PRs relating to data and metadata storage

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

[Feature Request] API Models for hot and warm tiering actions

4 participants